#include "application.hpp"

#include <model/repository.hpp>

#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 

namespace core
{

    application::application(int argc, char** argv)
    : QApplication(argc, argv),
    repos_(model::repository_ptr())
    {
        setApplicationName("gaia");
        setApplicationVersion("1.0");
        setOrganizationDomain("lochisoft.local");
        setOrganizationName("LochiSoft");
    }

    application::~application()
    {
        if (repos_)
        {
            repos_ = model::repository_ptr();
        }
    }

    void application::on_save_repository_as_request(const string& path)
    {
        on_create_repository_request(path);
    }

    void application::on_open_repository_request(const string& path)
    {
        open_repository(path);
    }

    void application::on_create_repository_request(const string& path)
    {
        repos_ = model::repository_ptr(new model::repository(path));
        repos_->bootstrap_data();
        
        save_repository();
        open_repository(path);
    }

    void application::save_repository()
    {
        std::ofstream f(repos_->path().c_str());
        if (!f.good())
        {
            throw std::runtime_error("could not open file for writing.");
        }

        boost::archive::text_oarchive oa(f);
        
        oa << repos_;
        f.close();

        emit repository_saved(repos_);

        std::cout << "Saved:" << std::endl
                << *repos_ << std::endl
                << "--- End of Broadcast" << std::endl;
    }

    void application::open_repository(const string& path)
    {
        repos_ = model::repository_ptr(new model::repository(path));

        std::ifstream f(path.c_str());
        if (!f.good())
        {
            throw std::runtime_error("could not open file for reading.");
        }

        boost::archive::text_iarchive ia(f);
        
        ia >> repos_;

        emit repository_opened(repos_);

        std::cout << "Loaded:" << std::endl
                << *repos_ << std::endl
                << "--- End of Broadcast" << std::endl;
    }

    void application::on_save_repository_request()
    {
        save_repository();
    }

    void application::on_close_repository_request()
    {
        emit repository_closed();

        processEvents();
        
        repos_ = model::repository_ptr();
    }
}
